<?php declare(strict_types=1);

namespace Umserv\ExchangeInterfaces\V1\Helpers;

/**
 * Класс хелпер для работ с ответами Http
 * <br><b>⚠️Имплементация Singleton, обращения через статические методы!</b>
 */
final class HttpResponse
{
    protected static self $instance;

    protected function __construct()
    {
    }

    private function __clone(): void
    {
    }

    public function __wakeup(): void
    {
        //todo: https://www.php.net/manual/ru/language.oop5.magic.php
    }

    public static function getInstance(): static
    {
        return static::$instance ?? static::$instance = new static();
    }

    public function SuccessResponse
    (\Umserv\ExchangeInterfaces\V1\Core\Http\Response $e,
     \Psr\Http\Message\ResponseInterface              &$response
    ): \Psr\Http\Message\ResponseInterface
    {
        return self::Response($e, $response);
    }

    public function ErrorResponse(
        \Exception|\Umserv\ExchangeInterfaces\V1\Core\Http\ErrorResponse $e,
        \Psr\Http\Message\ResponseInterface                             &$response
    ): \Psr\Http\Message\ResponseInterface
    {
        return self::Response($e, $response);
    }

    /**
     * Ответ сервера в виде ошибки
     *
     * @param Exception | \Umserv\ExchangeInterfaces\V1\Core\Http\BaseResponse $e Исключение или Мадель ответа
     * @param \Psr\Http\Message\ResponseInterface $response Ссылка на интерфейс ответа
     * @return \Psr\Http\Message\ResponseInterface          Интерфейс ответа
     */
    private function Response
    (
        \Exception|\Umserv\ExchangeInterfaces\V1\Core\Http\BaseResponse $e,
        \Psr\Http\Message\ResponseInterface                             &$response

    ): \Psr\Http\Message\ResponseInterface
    {

        if ($e instanceof \Exception) {
            $data = new \Umserv\ExchangeInterfaces\V1\Core\Http\ErrorResponse();
            $data->code = $e->getCode() > 0 ? $e->getCode() : 500;
            $data->message = (strlen($e->getMessage()) > 0) ? $e->getMessage() : 'Some server error.';
        } else {
            $data = $e;
        }

        $response
            ->getBody()
            ->write($data->getAsJson());

        return $response
            ->withHeader('Content-Type', 'application/json')
            ->withStatus($data->code);
    }
}